【学习笔记】BM 算法 & 常系数齐次线性递推
$Berlekamp-Massey$
实现时下标经常多一位或少一位-_-|| 我预 言不久的将来 BM 会沦为 xml 的脑内黑箱
大概做题思路就是:矩阵乘法都有递推式,数据范围超过 1000 就考虑 BM 求递推式然后乱搞
常系数齐次线性递推
求出递推式,接下来就要递推啦。
是照着 zhouzhendong 和 Winniechen 和 OI-wiki学习的,oi-wiki 没有那么多线代前置芝士。
解决什么问题?
给定一个数列,满足:
- $n \leq k$ 时,$f_n = a_n$
- $n > k$ 时,$f_n = \sum\limits_{i = 1}^k f_{n - i} * a_i$
众所周知矩阵生来就做这事儿的,但是 $n$ 比较大的时候就没前途。于是就出现了——特征多项式优化矩阵快速幂。求第 $n$ 项复杂度为 $O(k^2 log n)$
upd: 原先写的不好,删了。复读 oi-wiki。
从生成函数的角度来理解,就是将每个 $x^{n - i}$ 的系数乘上一个常数转移给了 $x^n$。
构造一个理论上存在的函数 $F$。
定义:$F(\sum a_i x^{n - i})$ 表示 $\sum a_i f_{n - i}$。
显然 $F$ 可以加、乘。$F(x^n) = f_n = F(\sum\limits_{i = 1}^k a_i x^{n - i})$,有 $F(x^n - \sum\limits_{i = 1}^k a_i x^{n - i}) = F(x^{n - k}(x^k - \sum\limits_{i = 1}^k a_i x^{k - i})) = 0$。
设 $\lambda = x^k - \sum\limits_{i = 1}^k a_i x^{k - i}$($\lambda$ 也称为该递推式的特征多项式),显然有 $F(\lambda) = 0$
$F(A(x) + x^d \lambda) = F(A(x)) + F(x^d \lambda) = F(A(x))$(这里的 $A(x)$ 是任意多项式,如果恰好是递推式的多项式那取模就是保留前 $k$ 项啦),就可以将 $A(x)$ 对 $\lambda$ 取模来降低 $A(x)$ 的次数。所以本质是个多项式取模。$O(k^2 logn)$ 的版本比较常用。
模板:要求 $f_n$,即求 $F(x^n) = F(x^n \mod \lambda)$,求出 $x^n \mod \lambda$ 后带入 $F$ 定义即可。
可以用多项式科技做到 $O(klogklogn)$。
template
1 | /* |
$THUSCH2017-如果奇迹有颜色$
这题比洛谷上的 Polya 模板题多了个相邻 $m$ 项颜色不能全不同的限制。
$|X/G| = \frac{1}{|G|} \sum_g m^{c(g)} = \frac{1}{|G|} \sum_k \varphi(n / k) * f(k)$
现在要算 $f(gcd = k)$ 的染色方案数。可以状压计算,状态数是 $m^{m}$,直接跑矩阵快速幂能拿到 $55$ 分的好成绩,然后我就不会了
题解告诉我要去学常系数齐次线性递推,我就滚去学了。厚厚,新知识!(于是就有了这篇拼凑起来的笔记
猜测递推式长度小于 $m^{m}$,借助超能力(打表)发现 $m = 7$ 就 $409$.
$NOI2017-泳池$
恰好用差分变为小于等于。设计 dp:$dp_{i, j}$ 表示有一块宽度为 $j$ 的区域,最下面 $i$ 行都是安全的,从下往上第 $i + 1$ 行及以上部分任意,且该区域内最大游泳场面积 $\leq K$ 的概率。那么有:
$$dp_{i, j} = dp_{i + 1, j} p^j + \sum\limits_{k = 1}^j dp_{i + 1, k - 1}dp_{i, j - k}(1 - p)p^{k - 1}$$
答案是 $dp_{0, n}$。
如果你打了表。。你就会发现 $dp_0$ 有递推式(谁这么熟练啊= =)于是一顿操作猛如虎回头一看二百五
$CF865G-Flowers\ and\ Chocolate$
不错的题,比前两道靠谱。写学习笔记里。
什么呀!做题还能被塞狗粮,真是够了。
题意好绕:买若干朵花和若干盒巧克力,使得花瓣数和巧克力块数相等。花和盒子摆放有顺序。
$n$ 这么大显然生成函数了。
- 花:$F(x) = (\sum x^{p_i})^n$
- 巧:$B(x) = \frac{1}{1 - \sum x^{c_i}}$
- $ans = \sum\limits_{n \geq 0} [x^n] F(x) [x^n] B(x)$
$B(x)$ 是个常系数递推式。可以简单的从组合意义(就是背包 dp = =)来理解:
- 设 $bin_i = \sum\limits_{j = 1}^B [c_j == i]$
- 设 $k = \max(c_i)$
- $dp_i = \sum\limits_{j = 1}^{k} bin_j dp_{i - j}$
那么求出递推式的特征多项式 $D(x) = x^k - \sum bin_i x^{k - i}$
假设知道了 $F(x)$ 某个 $[x^p]$,要知道 $B(x)$ 的 $[x^p]$ 就求出 $B(x) \mod D(x)$,得到一个 $250$ 次多项式,实际上这里取模就是保留前 $k$ 项,背包即可。
对 $F(x)$ 也求对 $D(x)$ 取模的结果以降次,具体来说是把 $x^{p_i}$ 对 $D(x)$ 取模并加在一起 $n$ 次方